home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / vprintf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-23  |  7.4 KB  |  335 lines

  1. /*
  2.  * Portable vfprintf  by Robert A. Larson <blarson@skat.usc.edu>
  3.  *
  4.  * Copyright 1989 Robert A. Larson.
  5.  * Distribution in any form is allowed as long as the author
  6.  * retains credit, changes are noted by their author and the
  7.  * copyright message remains intact.  This program comes as-is
  8.  * with no warentee of fitness for any purpouse.
  9.  *
  10.  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  11.  * the ansi printf specs.
  12.  *
  13.  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
  14.  * The use of goto is NOT a bug.
  15.  *
  16.  * Feb    7, 1989        blarson        First usenet release
  17.  *
  18.  * Changes for use with the IDA sendmail made by Paul Pomes, University
  19.  * of Illinois, Computing Services Office.  The original version is checked
  20.  * in to the RCS directory as number 1.1.
  21.  */
  22.  
  23. /* This code implements the vsprintf function, without relying on
  24.  * the existance of _doprint or other system specific code.
  25.  *
  26.  * Define NOVOID if void * is not a supported type.
  27.  *
  28.  * Two compile options are available for efficency:
  29.  *    INTSPRINTF    should be defined if sprintf is int and returns
  30.  *            the number of chacters formated.
  31.  *    LONGINT        should be defined if sizeof(long) == sizeof(int)
  32.  *
  33.  *    They only make the code smaller and faster, they need not be
  34.  *    defined.
  35.  *
  36.  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  37.  * than int in argument passing.  If this is definded, and LONGINT is not,
  38.  * the compiler must support the type unsingned long.
  39.  *
  40.  * Most quirks and bugs of the available sprintf fuction are duplicated,
  41.  * however * in the width and precision fields will work correctly
  42.  * even if sprintf does not support this, as will the n format.
  43.  *
  44.  * Bad format strings, or those with very long width and precision
  45.  * fields (including expanded * fields) will cause undesired results.
  46.  */
  47. #include "sendmail.h"
  48.  
  49. #ifdef NEED_VSPRINTF
  50.  
  51. # if !defined(lint)
  52. static char sccsid[] = "@(#)vprint.c    1.1 (USC) 2/7/89";
  53. static char rcsid[] = "@(#)$Id: vprintf.c,v 1.3 1991/06/24 14:12:03 paul Exp $";
  54. # endif /* not lint */
  55.  
  56. # ifndef __STDC__
  57. #  define NOVOID            /* a possibly reasonable assumption */
  58. # endif /* !__STDC__ */
  59.  
  60. # ifdef OSK            /* os9/68k can take advantage of both */
  61. #  define LONGINT
  62. #  define INTSPRINTF
  63. # endif /* OSK */
  64.  
  65. /* This must be a typedef not a #define! */
  66. # ifdef NOVOID
  67. typedef char *pointer;
  68. # else /* !NOVOID */
  69. typedef void *pointer;
  70. # endif /* NOVOID */
  71.  
  72. # ifdef INTSPRINTF
  73. #  define Sprintf(string,format,arg)    (sprintf((string),(format),(arg)))
  74. # else /* !INTSPRINTF */
  75. # define Sprintf(string,format,arg)    (\
  76.     sprintf((string),(format),(arg)),\
  77.     strlen(string)\
  78. )
  79. # endif /* INTSPRINTF */
  80.  
  81. typedef int *intp;
  82.  
  83. int
  84. # ifdef __STDC__
  85. vsprintf (char *dest, const char *format, va_list args)
  86. # else /* !__STDC__ */
  87. vsprintf (dest, format, args)
  88.     char    *dest;
  89.     register char *format;
  90.     va_list  args;
  91. # endif /* __STDC__ */
  92. {
  93.     register char *dp = dest;
  94.     register char c;
  95.     register char *tp;
  96.     char     tempfmt[64];
  97.  
  98. # ifndef LONGINT
  99.     int      longflag;
  100.  
  101. # endif /* !LONGINT */
  102.  
  103.     tempfmt[0] = '%';
  104.     while (c = *format++) {
  105.         if (c == '%') {
  106.             tp = &tempfmt[1];
  107. # ifndef LONGINT
  108.             longflag = 0;
  109. # endif /* !LONGINT */
  110.     continue_format:
  111.             switch (c = *format++) {
  112.                 case 's':
  113.                 *tp++ = c;
  114.                 *tp = '\0';
  115.                 dp += Sprintf (dp, tempfmt, va_arg (args, char *));
  116.                 break;
  117.                 case 'u':
  118.                 case 'x':
  119.                 case 'o':
  120.                 case 'X':
  121. # ifdef UNSIGNEDSPECIAL
  122.                 *tp++ = c;
  123.                 *tp = '\0';
  124. #  ifndef LONGINT
  125.                 if (longflag)
  126.                     dp += Sprintf (dp, tempfmt, va_arg (args, unsigned long));
  127.                 else
  128. #  endif /* !LONGINT */
  129.                     dp += Sprintf (dp, tempfmt, va_arg (args, unsigned));
  130.                 break;
  131. # endif /* UNSIGNEDSPECIAL */
  132.                 case 'd':
  133.                 case 'c':
  134.                 case 'i':
  135.                 *tp++ = c;
  136.                 *tp = '\0';
  137. # ifndef LONGINT
  138.                 if (longflag)
  139.                     dp += Sprintf (dp, tempfmt, va_arg (args, long));
  140.                 else
  141. # endif /* !LONGINT */
  142.                     dp += Sprintf (dp, tempfmt, va_arg (args, int));
  143.                 break;
  144.                 case 'f':
  145.                 case 'e':
  146.                 case 'E':
  147.                 case 'g':
  148.                 case 'G':
  149.                 *tp++ = c;
  150.                 *tp = '\0';
  151.                 dp += Sprintf (dp, tempfmt, va_arg (args, double));
  152.                 break;
  153.                 case 'p':
  154.                 *tp++ = c;
  155.                 *tp = '\0';
  156.                 dp += Sprintf (dp, tempfmt, va_arg (args, pointer));
  157.                 break;
  158.                 case '-':
  159.                 case '+':
  160.                 case '0':
  161.                 case '1':
  162.                 case '2':
  163.                 case '3':
  164.                 case '4':
  165.                 case '5':
  166.                 case '6':
  167.                 case '7':
  168.                 case '8':
  169.                 case '9':
  170.                 case '.':
  171.                 case ' ':
  172.                 case '#':
  173.                 case 'h':
  174.                 *tp++ = c;
  175.                 goto continue_format;
  176.                 case 'l':
  177. # ifndef LONGINT
  178.                 longflag = 1;
  179.                 *tp++ = c;
  180. # endif /* !LONGINT */
  181.                 goto continue_format;
  182.                 case '*':
  183.                 tp += Sprintf (tp, "%d", va_arg (args, int));
  184.                 goto continue_format;
  185.                 case 'n':
  186.                 *va_arg (args, intp) = dp - dest;
  187.                 break;
  188.                 case '%':
  189.                 default:
  190.                 *dp++ = c;
  191.                 break;
  192.             }
  193.         } else
  194.             *dp++ = c;
  195.     }
  196.     *dp = '\0';
  197.     return dp - dest;
  198. }
  199.  
  200.  
  201. int 
  202. # ifdef __STDC__
  203. vfprintf (FILE *dest, const char *format, va_list args)
  204. # else /* !__STDC__ */
  205. vfprintf (dest, format, args)
  206.     FILE    *dest;
  207.     register char *format;
  208.     va_list  args;
  209. # endif /* __STDC__ */
  210. {
  211.     register char c;
  212.     register char *tp;
  213.     register int count = 0;
  214.     char     tempfmt[64];
  215.  
  216. # ifndef LONGINT
  217.     int      longflag;
  218.  
  219. # endif /* !LONGINT */
  220.  
  221.     tempfmt[0] = '%';
  222.     while (c = *format++) {
  223.         if (c == '%') {
  224.             tp = &tempfmt[1];
  225. # ifndef LONGINT
  226.             longflag = 0;
  227. # endif /* !LONGINT */
  228.     continue_format:
  229.             switch (c = *format++) {
  230.                 case 's':
  231.                 *tp++ = c;
  232.                 *tp = '\0';
  233.                 count += fprintf (dest, tempfmt, va_arg (args, char *));
  234.                 break;
  235.                 case 'u':
  236.                 case 'x':
  237.                 case 'o':
  238.                 case 'X':
  239. # ifdef UNSIGNEDSPECIAL
  240.                 *tp++ = c;
  241.                 *tp = '\0';
  242. #  ifndef LONGINT
  243.                 if (longflag)
  244.                     count += fprintf (dest, tempfmt, va_arg (args, unsigned long));
  245.                 else
  246. #  endif /* !LONGINT */
  247.                     count += fprintf (dest, tempfmt, va_arg (args, unsigned));
  248.                 break;
  249. # endif /* UNSIGNEDSPECIAL */
  250.                 case 'd':
  251.                 case 'c':
  252.                 case 'i':
  253.                 *tp++ = c;
  254.                 *tp = '\0';
  255. # ifndef LONGINT
  256.                 if (longflag)
  257.                     count += fprintf (dest, tempfmt, va_arg (args, long));
  258.                 else
  259. # endif /* !LONGINT */
  260.                     count += fprintf (dest, tempfmt, va_arg (args, int));
  261.                 break;
  262.                 case 'f':
  263.                 case 'e':
  264.                 case 'E':
  265.                 case 'g':
  266.                 case 'G':
  267.                 *tp++ = c;
  268.                 *tp = '\0';
  269.                 count += fprintf (dest, tempfmt, va_arg (args, double));
  270.                 break;
  271.                 case 'p':
  272.                 *tp++ = c;
  273.                 *tp = '\0';
  274.                 count += fprintf (dest, tempfmt, va_arg (args, pointer));
  275.                 break;
  276.                 case '-':
  277.                 case '+':
  278.                 case '0':
  279.                 case '1':
  280.                 case '2':
  281.                 case '3':
  282.                 case '4':
  283.                 case '5':
  284.                 case '6':
  285.                 case '7':
  286.                 case '8':
  287.                 case '9':
  288.                 case '.':
  289.                 case ' ':
  290.                 case '#':
  291.                 case 'h':
  292.                 *tp++ = c;
  293.                 goto continue_format;
  294.                 case 'l':
  295. # ifndef LONGINT
  296.                 longflag = 1;
  297.                 *tp++ = c;
  298. # endif /* !LONGINT */
  299.                 goto continue_format;
  300.                 case '*':
  301.                 tp += Sprintf (tp, "%d", va_arg (args, int));
  302.                 goto continue_format;
  303.                 case 'n':
  304.                 *va_arg (args, intp) = count;
  305.                 break;
  306.                 case '%':
  307.                 default:
  308.                 putc (c, dest);
  309.                 count++;
  310.                 break;
  311.             }
  312.         } else {
  313.             putc (c, dest);
  314.             count++;
  315.         }
  316.     }
  317.     return count;
  318. }
  319.  
  320. int
  321. # ifdef __STDC__
  322. vprintf (const char *format, va_list args)
  323. # else /* !__STDC__ */
  324. vprintf (format, args)
  325.     register char *format;
  326.     va_list  args;
  327. # endif /* __STDC__ */
  328. {
  329.     register int nchars;
  330.     nchars = vfprintf (stdout, format, args);
  331.     return nchars;
  332. }
  333.  
  334. #endif /* NEED_VSPRINTF */
  335.